"""
单例   ---单个实例
设计模式
让类创建的对象，在系统中只有唯一的一个实例
每一次执行 类名() 返回的对象，内存地址是相同的
应用:
音乐播放对象 同一时间只播放一首 只有一个播放对象
回收站对象
打印机对象

__new__方法
使用 类名()创建对象时 首先调用new方法为对象分配空间
new是由object基类提供的内置静态方法
主要作用
    在内存中为对象分配空间
    返回对象的引用
python在获得对象ed引用后将引用作为第一个参数传递给__init__方法
重写__new__方法的代码非常固定
重写__new__方法一定要 return supper().__new__(cls)
否则python得不到分配了空间的对象引用，就不会调用对象的初始化方法
__new__是一个静态方法，在调用时需要主动传递cls参数

"""


#重写new方法（基本固定）

# class A(object):
#     def __new__(cls, *args, **kwargs):
#         print("创建对象时new方法在init之前被自动调用了")
#
#         # 为对象分配空间
#         aaa = super().__new__(cls)
#
#         # 返回对象的引用，如果没有return,init方法则不会被调用
#         return aaa
#
#     def __init__(self):
#         print("inti方法")
#
# a = A()
# print(a)


"""
单例实现
定义一个类属性初始值为None，用于记录单例对象的引用
重写__new__方法
如果类属性 is None，调用父类方法分配空间，并在类属性中记录结果
返回类属性中记录的对象引用
"""

# class A(object):
#     aaa = None
#     # 定义类属性初始值为None  用于记录单例对象的引用
#
#     def __new__(cls, *args, **kwargs):
#         # 判断类属性是否是空对象
#         # 如果为空，调用父类的new方法分配空间
#         if cls.aaa == None:
#             cls.aaa = super().__new__(cls)
#         # 返回类属性保存的对象引用
#         return cls.aaa
#     def __init__(self):
#         pass
#
# a = A()
# print(a)
# b = A()
# print(b)
#
# # 两个对象都在同一个地址


"""
只执行一次init方法
定义一个类属性标记是否执行过init初始值为False
在init方法中判断类属性如果为False，执行init，并将值设置为True
这样再次调用init时，init中则不被执行
"""

#
# class A(object):
#     a = None
#     b = False
#     def __new__(cls, *args, **kwargs):
#         if cls.a == None:
#             cls.a = super().__new__(cls)
#         return cls.a
#     def __init__(self):
#         if self.b == False:
#             print("初始化一次")
#             self.b = True
#
# aaa = A()
# print(aaa)
# bbb = A()
# print(bbb)




